/* SERVER.C */

/*
	Copyright (C) 2010 by Lesnikov Andrey <ozkriff@gmail.com>
	This file is part of ozkriff_game_2.

	ozkriff_game_2 is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	ozkriff_game_2 is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with ozkriff_game_2.  If not, see <http://www.gnu.org/licenses/>.

	See the COPYING file for more details.
*/

#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include "SDL/SDL.h"
#include "SDL/SDL_net.h"

#include "defines.h"
#include "server.h"

client *clients = NULL;

// cc - exeption. Pass NULL, if you want to send to everyone
void
send_all(client *cc, uint8_t n)
{
	client *c = clients;
	while(c)
	{
		if(cc != c)
			SDLNet_TCP_Send(c->sock, &n, 1);
		c = c->next;
	}
}


#undef main
int
main(void)
{
	IPaddress	ip;
	TCPsocket	sock;
	SDLNet_SocketSet set;
	TCPsocket	server;
	
	SDL_Init(0);
	SDLNet_Init();

	SDLNet_ResolveHost(&ip,NULL,2000);
	server = SDLNet_TCP_Open(&ip);

	set = SDLNet_AllocSocketSet(4+1); //4 clients+server
	SDLNet_TCP_AddSocket(set, server);

	//keep waiting untill 3 clients connect
	int NUMCLIENTS = 0;
	while(NUMCLIENTS < 2)
	{
		if(SDLNet_CheckSockets(set, 100) && 
				SDLNet_SocketReady(server))
		{
			NUMCLIENTS++;

			sock = SDLNet_TCP_Accept(server);

			client *c = malloc(sizeof(client));
			c->next = clients;
			c->sock = sock;
			clients = c;
			SDLNet_TCP_AddSocket(set, sock);
			SDLNet_TCP_Recv(c->sock, &(c->id), 1);
			
			printf("add client. id=%u;\n", c->id);
		}
	}

	//activate first client
	uint8_t m = NET_T_MODE;
	SDLNet_TCP_Send(clients->sock, &m, 1);

	while(1)
	{
		int numready = SDLNet_CheckSockets(set, 100);

		client *c = clients;
		while(numready && c)
		{
			if(SDLNet_SocketReady(c->sock))
			{

				uint8_t m;
				SDLNet_TCP_Recv(c->sock, &m, 1);

				switch(m)
				{
					default: break;
					
					case NET_MOVE:
					{
						numready--;
						printf("MOVE (%u) ", c->id);

						uint8_t x1, y1, x2, y2;
						SDLNet_TCP_Recv(c->sock, &x1, 1);
						SDLNet_TCP_Recv(c->sock, &y1, 1);
						SDLNet_TCP_Recv(c->sock, &x2, 1);
						SDLNet_TCP_Recv(c->sock, &y2, 1);
						
						printf("(%u;", (unsigned int)x1);
						printf("%u)->", (unsigned int)y1);
						printf("(%u;", (unsigned int)x2);
						printf("%u)\n", (unsigned int)y2);

						send_all(c, m);
						send_all(c, c->id);
						send_all(c, x1);
						send_all(c, y1);
						send_all(c, x2);
						send_all(c, y2);

						break;
					};
					
					case NET_FIGHT:
					{
						numready--;
						printf("FIGHT (%u) ", c->id);

						uint8_t x1, y1, x2, y2;
						SDLNet_TCP_Recv(c->sock, &x1, 1);
						SDLNet_TCP_Recv(c->sock, &y1, 1);
						SDLNet_TCP_Recv(c->sock, &x2, 1);
						SDLNet_TCP_Recv(c->sock, &y2, 1);
						
						printf("(%u;", (unsigned int)x1);
						printf("%u)->", (unsigned int)y1);
						printf("(%u;", (unsigned int)x2);
						printf("%u)\n", (unsigned int)y2);
						
						send_all(c, m);
						send_all(c, c->id);
						send_all(c, x1);
						send_all(c, y1);
						send_all(c, x2);
						send_all(c, y2);

						break;
					};

					case NET_T_MODE:
					{
						numready--;
						puts("next player.");

						//uint8_t m = NET_T_MODE;
						if(c->next)
						{
							SDLNet_TCP_Send(c->next->sock, &m, 1);
						}
						else
						{
							puts("END TURN!");
							SDLNet_TCP_Send(clients->sock, &m, 1);
						}
						
						break;
					}
					
					case NET_CH_TERRAIN:
					{
						numready--;
						//puts("changin terrain");
						
						uint8_t x, y;
						SDLNet_TCP_Recv(c->sock, &x, 1);
						SDLNet_TCP_Recv(c->sock, &y, 1);
						
						send_all(c, m);
						send_all(c, x);
						send_all(c, y);
						
						break;
					}

					case NET_QUIT:
					{
						numready--;
						//uint8_t m = NET_QUIT;
						send_all(NULL, m);
						puts("DEAD");
						exit(0);
						break;
					}
				}
			}
			c = c->next;
		}
	}

	SDLNet_Quit();
	SDL_Quit();

	return(0);
}
